﻿using System;
using System.Collections.Generic;

namespace DotNetClient
{
    public class EventManager : IDisposable
    {
        private Dictionary<byte, Action<Message>> _callBackMap;
        private Dictionary<string, List<Action<Message>>> _eventMap;

        public EventManager()
        {
            _callBackMap = new Dictionary<byte, Action<Message>>();
            _eventMap = new Dictionary<string, List<Action<Message>>>();
        }

        /// <summary>
        /// Adds callback to callBackMap by id
        /// </summary>
        /// <param name="id"></param>
        /// <param name="callback"></param>
        public void AddCallBack(byte id, Action<Message> callback)
        {
            if (id > 0 && callback != null)
            {
                _callBackMap.Add(id, callback);
            }
        }

        /// <summary>
        /// Invoke the callback when the server return messge
        /// </summary>
        /// <param name="id"></param>
        /// <param name="data"></param>
        public void InvokeCallBack(byte id, Message data)
        {
            if (!_callBackMap.ContainsKey(id)) return;

            _callBackMap[id].Invoke(data);
            _callBackMap.Remove(id);
        }

        /// <summary>
        /// Adds the event to eventMap by name
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="callback"></param>
        public void AddOnEvent(string eventName, Action<Message> callback)
        {
            List<Action<Message>> list = null;
            if (_eventMap.TryGetValue(eventName, out list))
            {
                list.Add(callback);
            }
            else
            {
                list = new List<Action<Message>>();
                list.Add(callback);
                _eventMap.Add(eventName, list);
            }
        }

        /// <summary>
        /// If the event exists,invoke the event when server return messge
        /// </summary>
        /// <param name="route"></param>
        /// <param name="msg"></param>
        public void InvokeOnEvent(string route, Message msg)
        {
            if (!_eventMap.ContainsKey(route)) return;

            List<Action<Message>> list = _eventMap[route];
            foreach (Action<Message> action in list) action.Invoke(msg);
        }

        /// <summary>
        /// Dispose() calls Dispose(true)
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// The bulk of the clean-up code is implemented in Dispose(bool)
        /// </summary>
        /// <param name="disposing"></param>
        protected void Dispose(bool disposing)
        {
            _callBackMap.Clear();
            _eventMap.Clear();
        }
    }
}
